//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include <RenderLibServer.h>
////////////////////////////////////////////////////////////////////////////
//                              Blit relatives                            //
////////////////////////////////////////////////////////////////////////////

Void RGB24Blit2RGB24(
                Address dst, Int32 dstX, Int32 dstY, Int32 dstPitch,
                Address src, Int32 srcX, Int32 srcY, Int32 width, Int32 height,
                Int32 srcPitch, UInt8 srcOpacity)
{
    assert(dst && src);
    assert(width > 0 && height > 0);
    assert(dstPitch > 0 && srcPitch > 0);
    assert(dstX >= 0 && dstY >= 0 && srcX >= 0 && srcY >= 0);

    src += srcPitch * srcY + (srcX<<2);
    dst += dstPitch * dstY + (dstX<<2);

    if (0xFF == srcOpacity) {
        while (height-- > 0) {
            ScanLineRGB24ToRGB24(dst, src, width);

            src += srcPitch;
            dst += dstPitch;
        }
    }
    else if (0x00 != srcOpacity ) {
        while (height-- > 0) {
            ScanLineRGB24ToRGB24WithOpacity(
                    dst, src, width, srcOpacity);

            src += srcPitch;
            dst += dstPitch;
        }
    }
}

Void ARGB32Blit2RGB24(
                Address dst, Int32 dstX, Int32 dstY, Int32 dstPitch,
                Address src, Int32 srcX, Int32 srcY, Int32 width, Int32 height,
                Int32 srcPitch, UInt8 srcOpacity)
{
    assert(dst && src);
    assert(width > 0 && height > 0);
    assert(dstPitch > 0 && srcPitch > 0);
    assert(dstX >= 0 && dstY >= 0 && srcX >= 0 && srcY >= 0);

    src += srcPitch * srcY + (srcX<<2);
    dst += dstPitch * dstY + (dstX<<2);

    if (0xFF == srcOpacity) {
        while (height-- > 0) {
            ScanLineARGB32ToRGB24(dst, src, width);

            src += srcPitch;
            dst += dstPitch;
        }
    }
    else if (0x00 != srcOpacity ) {
        while (height-- > 0) {
            ScanLineARGB32ToRGB24WithOpacity(
                    dst, src, width, srcOpacity);

            src += srcPitch;
            dst += dstPitch;
        }
    }
}

Void RGB24Blit2ARGB32(
                Address dst, Int32 dstX, Int32 dstY, Int32 dstPitch,
                Address src, Int32 srcX, Int32 srcY, Int32 width, Int32 height,
                Int32 srcPitch, UInt8 srcOpacity)
{
    assert(dst && src);
    assert(width > 0 && height > 0);
    assert(dstPitch > 0 && srcPitch > 0);
    assert(dstX >= 0 && dstY >= 0 && srcX >= 0 && srcY >= 0);

    src += srcPitch * srcY + (srcX<<2);
    dst += dstPitch * dstY + (dstX<<2);

    if (0xFF == srcOpacity) {
        while (height-- > 0) {
            ScanLineRGB24ToARGB32(dst, src, width);

            src += srcPitch;
            dst += dstPitch;
        }
    }
    else if (0x00 != srcOpacity ) {
        while (height-- > 0) {
            ScanLineRGB24ToARGB32WithOpacity(
                    dst, src, width, srcOpacity);

            src += srcPitch;
            dst += dstPitch;
        }
    }
}

Void ARGB32Blit2ARGB32(
                Address dst, Int32 dstX, Int32 dstY, Int32 dstPitch,
                Address src, Int32 srcX, Int32 srcY, Int32 width, Int32 height,
                Int32 srcPitch, UInt8 srcOpacity)
{
    assert(dst && src);
    assert(width > 0 && height > 0);
    assert(dstPitch > 0 && srcPitch > 0);
    assert(dstX >= 0 && dstY >= 0 && srcX >= 0 && srcY >= 0);

    src += srcPitch * srcY + (srcX<<2);
    dst += dstPitch * dstY + (dstX<<2);

    if (0xFF == srcOpacity) {
        while (height-- > 0) {
            ScanLineARGB32ToARGB32(dst, src, width);

            src += srcPitch;
            dst += dstPitch;
        }
    }
    else if (0x00 != srcOpacity ) {
        while (height-- > 0) {
            ScanLineARGB32ToARGB32WithOpacity(
                    dst, src, width, srcOpacity);

            src += srcPitch;
            dst += dstPitch;
        }
    }
}

Void A8Blit2RGB24(
                Address dst, Int32 dstX, Int32 dstY, Int32 dstPitch,
                Address src, Int32 srcX, Int32 srcY, Int32 width, Int32 height,
                Int32 srcPitch, Color srcColor, UInt8 srcOpacity)
{
    assert(dst && src);
    assert(width > 0 && height > 0);
    assert(dstPitch > 0 && srcPitch > 0);
    assert(dstX >= 0 && dstY >= 0 && srcX >= 0 && srcY >= 0);

    Pixel color = *(Pixel *)&srcColor;

    if (0 == srcOpacity) {
        return;
    }
    else if (0xFF != srcOpacity) {
        color.a = (color.a * srcOpacity)>>8;
        color.r = (color.r * srcOpacity)>>8;
        color.g = (color.g * srcOpacity)>>8;
        color.b = (color.b * srcOpacity)>>8;
    }

    src += srcPitch * srcY + srcX;
    dst += dstPitch * dstY + (dstX<<2);

    if (0xFF == color.a) {
        while (height-- > 0) {
            ScanLineA8ToRGB24(dst, src, width, color);

            src += srcPitch;
            dst += dstPitch;
        }
    }
    else if (0x00 != color.a) {
        while (height-- > 0) {
            ScanLineA8ToRGB24WithColorAlpha(
                    dst, src, width, color);

            src += srcPitch;
            dst += dstPitch;
        }
    }
}

Void A8Blit2ARGB32(
                Address dst, Int32 dstX, Int32 dstY, Int32 dstPitch,
                Address src, Int32 srcX, Int32 srcY, Int32 width, Int32 height,
                Int32 srcPitch, Color srcColor, UInt8 srcOpacity)
{
    assert(dst && src);
    assert(width > 0 && height > 0);
    assert(dstPitch > 0 && srcPitch > 0);
    assert(dstX >= 0 && dstY >= 0 && srcX >= 0 && srcY >= 0);

    Pixel color = *(Pixel *)&srcColor;

    if (0 == srcOpacity) {
        return;
    }
    else if (0xFF != srcOpacity) {
        color.a = (color.a * srcOpacity)>>8;
        color.r = (color.r * srcOpacity)>>8;
        color.g = (color.g * srcOpacity)>>8;
        color.b = (color.b * srcOpacity)>>8;
    }

    src += srcPitch * srcY + srcX;
    dst += dstPitch * dstY + (dstX<<2);

    if (0xFF == color.a) {
        while (height-- > 0) {
            ScanLineA8ToARGB32(dst, src, width, color);

            src += srcPitch;
            dst += dstPitch;
        }
    }
    else if (0x00 != color.a) {
        while (height-- > 0) {
            ScanLineA8ToARGB32WithColorAlpha(
                    dst, src, width, color);

            src += srcPitch;
            dst += dstPitch;
        }
    }
}

Void SetColorARGB32(
                Address dst, Int32 dstX, Int32 dstY, Int32 width, Int32 height,
                Int32 dstPitch, Color srcColor, UInt8 srcOpacity)
{
    assert(dst);
    assert(width > 0 && height > 0);
    assert(dstPitch > 0);
    assert(dstX >= 0 && dstY >= 0);

    Pixel color = *(Pixel *)&srcColor;

    if (0 == srcOpacity) {
        return;
    }
    else if (0xFF != srcOpacity) {
        color.a = (color.a * srcOpacity)>>8;
        color.r = (color.r * srcOpacity)>>8;
        color.g = (color.g * srcOpacity)>>8;
        color.b = (color.b * srcOpacity)>>8;
    }

    dst += dstPitch * dstY + (dstX<<2);

    while (height-- > 0) {
        ScanLineSetColorARGB32(dst, width, color);

        dst += dstPitch;
    }
}

Void BlendColor(
                Address dst, Int32 dstX, Int32 dstY, Int32 width, Int32 height,
                Int32 dstPitch, Color srcColor, UInt8 srcOpacity)
{
    assert(dst);
    assert(width > 0 && height > 0);
    assert(dstPitch > 0);
    assert(dstX >= 0 && dstY >= 0);

    Pixel color = *(Pixel *)&srcColor;

    if (0 == srcOpacity) {
        return;
    }
    else if (0xFF != srcOpacity) {
        color.a = (color.a * srcOpacity)>>8;
        color.r = (color.r * srcOpacity)>>8;
        color.g = (color.g * srcOpacity)>>8;
        color.b = (color.b * srcOpacity)>>8;
    }

    dst += dstPitch * dstY + (dstX<<2);

    if (0xFF == color.a) {
        while (height-- > 0) {
            ScanLineSetColorARGB32(dst, width, color);

            dst += dstPitch;
        }
    }
    else if (0x00 != color.a) {
        while (height-- > 0) {
            ScanLineSetColorARGB32WithColorAlpha(dst, width, color);

            dst += dstPitch;
        }
    }
}

//////////////////////////////////////////////////////////////////////////////
//                          Stretch Blit relatives                          //
//////////////////////////////////////////////////////////////////////////////

Void RGB24StretchBlit2RGB24(
                Address dst, Int32 dstX, Int32 dstY,
                Int32 dstWidth, Int32 dstHeight, Int32 dstPitch,
                Address src, Int32 srcX, Int32 srcY,
                Int32 srcWidth, Int32 srcHeight, Int32 srcPitch,
                UInt8 srcOpacity,
                UInt8 interpolation)
{
    assert(dst && src);
    assert(srcWidth > 0 && srcHeight > 0);
    assert(dstWidth > 0 && dstHeight > 0);
    assert(dstX >= 0 && dstY >= 0 && srcX >= 0 && srcY >= 0);

    UInt32 srcy_16 = 0;

    src += srcPitch * srcY + (srcX<<2);
    dst += dstPitch * dstY + (dstX<<2);

    if (0xFF == srcOpacity) {
        if (interpolation) {
            UInt32 xrIntFloat_16 = ((srcWidth-1)<<16) / dstWidth;
            UInt32 yrIntFloat_16 = ((srcHeight-1)<<16) / dstHeight;

            while (dstHeight-- > 0) {
                UInt32 v_8 = (srcy_16 & 0xFFFF)>>8;

                BilinearScanLineRGB24ToRGB24(
                        dst,
                        (src + srcPitch * (srcy_16>>16)),
                        srcPitch, v_8, xrIntFloat_16, dstWidth);

                dst+= dstPitch;
                srcy_16 += yrIntFloat_16;
            }
        }
        else {
            UInt32 xrIntFloat_16 = (srcWidth<<16) / dstWidth;
            UInt32 yrIntFloat_16 = (srcHeight<<16) / dstHeight;

            while (dstHeight-- > 0) {
                ZoomScanLineRGB24ToRGB24(
                        dst, dstWidth,
                        (src + srcPitch * (srcy_16>>16)),
                        xrIntFloat_16);

                dst+= dstPitch;
                srcy_16 += yrIntFloat_16;
            }
        }
    }
    else if (0x00 != srcOpacity) {
       if (interpolation) {
            UInt32 xrIntFloat_16 = ((srcWidth-1)<<16) / dstWidth;
            UInt32 yrIntFloat_16 = ((srcHeight-1)<<16) / dstHeight;

            while (dstHeight-- > 0) {
                UInt32 v_8 = (srcy_16 & 0xFFFF)>>8;

                BilinearScanLineRGB24ToRGB24WithOpacity(
                        dst,
                        (src + srcPitch * (srcy_16>>16)),
                        srcPitch, v_8, xrIntFloat_16, dstWidth, srcOpacity);

                dst+= dstPitch;
                srcy_16 += yrIntFloat_16;
            }
        }
        else {
            UInt32 xrIntFloat_16 = (srcWidth<<16) / dstWidth;
            UInt32 yrIntFloat_16 = (srcHeight<<16) / dstHeight;

            while (dstHeight-- > 0) {
                ZoomScanLineRGB24ToRGB24WithOpacity(
                        dst, dstWidth,
                        (src + srcPitch * (srcy_16>>16)),
                        xrIntFloat_16, srcOpacity);

                dst+= dstPitch;
                srcy_16 += yrIntFloat_16;
            }
        }
    }
}

Void ARGB32StretchBlit2RGB24(
                Address dst, Int32 dstX, Int32 dstY,
                Int32 dstWidth, Int32 dstHeight, Int32 dstPitch,
                Address src, Int32 srcX, Int32 srcY,
                Int32 srcWidth, Int32 srcHeight, Int32 srcPitch,
                UInt8 srcOpacity,
                UInt8 interpolation)
{
    assert(dst && src);
    assert(srcWidth > 0 && srcHeight > 0);
    assert(dstWidth > 0 && dstHeight > 0);
    assert(dstX >= 0 && dstY >= 0 && srcX >= 0 && srcY >= 0);

    UInt32 srcy_16 = 0;

    src += srcPitch * srcY + (srcX<<2);
    dst += dstPitch * dstY + (dstX<<2);

    if (0xFF == srcOpacity) {
        if (interpolation) {
            UInt32 xrIntFloat_16 = ((srcWidth-1)<<16) / dstWidth;
            UInt32 yrIntFloat_16 = ((srcHeight-1)<<16) / dstHeight;

            while (dstHeight-- > 0) {
                UInt32 v_8 = (srcy_16 & 0xFFFF)>>8;

                BilinearScanLineARGB32ToRGB24(
                        dst,
                        (src + srcPitch * (srcy_16>>16)),
                        srcPitch, v_8, xrIntFloat_16, dstWidth);

                dst+= dstPitch;
                srcy_16 += yrIntFloat_16;
            }
        }
        else {
            UInt32 xrIntFloat_16 = (srcWidth<<16) / dstWidth;
            UInt32 yrIntFloat_16 = (srcHeight<<16) / dstHeight;

            while (dstHeight-- > 0) {
                ZoomScanLineARGB32ToRGB24(
                        dst, dstWidth,
                        (src + srcPitch * (srcy_16>>16)),
                        xrIntFloat_16);

                dst+= dstPitch;
                srcy_16 += yrIntFloat_16;
            }
        }
    }
    else if (0x00 != srcOpacity) {
       if (interpolation) {
            UInt32 xrIntFloat_16 = ((srcWidth-1)<<16) / dstWidth;
            UInt32 yrIntFloat_16 = ((srcHeight-1)<<16) / dstHeight;

            while (dstHeight-- > 0) {
                UInt32 v_8 = (srcy_16 & 0xFFFF)>>8;

                BilinearScanLineARGB32ToRGB24WithOpacity(
                        dst,
                        (src + srcPitch * (srcy_16>>16)),
                        srcPitch, v_8, xrIntFloat_16,  dstWidth, srcOpacity);

                dst+= dstPitch;
                srcy_16 += yrIntFloat_16;
            }
        }
        else {
            UInt32 xrIntFloat_16 = (srcWidth<<16) / dstWidth;
            UInt32 yrIntFloat_16 = (srcHeight<<16) / dstHeight;

            while (dstHeight-- > 0) {
                ZoomScanLineARGB32ToRGB24WithOpacity(
                        dst, dstWidth,
                        (src + srcPitch * (srcy_16>>16)),
                        xrIntFloat_16, srcOpacity);

                dst+= dstPitch;
                srcy_16 += yrIntFloat_16;
            }
        }
    }
}

Void RGB24StretchBlit2ARGB32(
                Address dst, Int32 dstX, Int32 dstY,
                Int32 dstWidth, Int32 dstHeight, Int32 dstPitch,
                Address src, Int32 srcX, Int32 srcY,
                Int32 srcWidth, Int32 srcHeight, Int32 srcPitch,
                UInt8 srcOpacity,
                UInt8 interpolation)
{
    assert(dst && src);
    assert(srcWidth > 0 && srcHeight > 0);
    assert(dstWidth > 0 && dstHeight > 0);
    assert(dstX >= 0 && dstY >= 0 && srcX >= 0 && srcY >= 0);

    UInt32 srcy_16 = 0;

    src += srcPitch * srcY + (srcX<<2);
    dst += dstPitch * dstY + (dstX<<2);

    if (0xFF == srcOpacity) {
        if (interpolation) {
            UInt32 xrIntFloat_16 = ((srcWidth-1)<<16) / dstWidth;
            UInt32 yrIntFloat_16 = ((srcHeight-1)<<16) / dstHeight;

            while (dstHeight-- > 0) {
                UInt32 v_8 = (srcy_16 & 0xFFFF)>>8;

                BilinearScanLineRGB24ToARGB32(
                        dst,
                        (src + srcPitch * (srcy_16>>16)),
                        srcPitch, v_8, xrIntFloat_16, dstWidth);

                dst+= dstPitch;
                srcy_16 += yrIntFloat_16;
            }

        }
        else {
            UInt32 xrIntFloat_16 = (srcWidth<<16) / dstWidth;
            UInt32 yrIntFloat_16 = (srcHeight<<16) / dstHeight;

            while (dstHeight-- > 0) {
                ZoomScanLineRGB24ToARGB32(
                        dst, dstWidth,
                        (src + srcPitch * (srcy_16>>16)),
                        xrIntFloat_16);

                dst+= dstPitch;
                srcy_16 += yrIntFloat_16;
            }
        }
    }
    else if (0x00 != srcOpacity) {
       if (interpolation) {
            UInt32 xrIntFloat_16 = ((srcWidth-1)<<16) / dstWidth;
            UInt32 yrIntFloat_16 = ((srcHeight-1)<<16) / dstHeight;

            while (dstHeight-- > 0) {
                UInt32 v_8 = (srcy_16 & 0xFFFF)>>8;

                BilinearScanLineRGB24ToARGB32WithOpacity(
                        dst,
                        (src + srcPitch * (srcy_16>>16)),
                        srcPitch, v_8, xrIntFloat_16, dstWidth, srcOpacity);

                dst+= dstPitch;
                srcy_16 += yrIntFloat_16;
            }
        }
        else {
            UInt32 xrIntFloat_16 = (srcWidth<<16) / dstWidth;
            UInt32 yrIntFloat_16 = (srcHeight<<16) / dstHeight;

            while (dstHeight-- > 0) {
                ZoomScanLineRGB24ToARGB32WithOpacity(
                        dst, dstWidth,
                        (src + srcPitch * (srcy_16>>16)),
                        xrIntFloat_16, srcOpacity);

                dst+= dstPitch;
                srcy_16 += yrIntFloat_16;
            }
        }
    }
}

Void ARGB32StretchBlit2ARGB32(
                Address dst, Int32 dstX, Int32 dstY,
                Int32 dstWidth, Int32 dstHeight, Int32 dstPitch,
                Address src, Int32 srcX, Int32 srcY,
                Int32 srcWidth, Int32 srcHeight, Int32 srcPitch,
                UInt8 srcOpacity,
                UInt8 interpolation)
{
    assert(dst && src);
    assert(srcWidth > 0 && srcHeight > 0);
    assert(dstWidth > 0 && dstHeight > 0);
    assert(dstX >= 0 && dstY >= 0 && srcX >= 0 && srcY >= 0);

    UInt32 srcy_16 = 0;

    src += srcPitch * srcY + (srcX<<2);
    dst += dstPitch * dstY + (dstX<<2);

    if (0xFF == srcOpacity) {
        if (interpolation) {
            UInt32 xrIntFloat_16 = ((srcWidth-1)<<16) / dstWidth;
            UInt32 yrIntFloat_16 = ((srcHeight-1)<<16) / dstHeight;

            while (dstHeight-- > 0) {
                UInt32 v_8 = (srcy_16 & 0xFFFF)>>8;

                BilinearScanLineARGB32ToARGB32(
                        dst,
                        (src + srcPitch * (srcy_16>>16)),
                        srcPitch, v_8, xrIntFloat_16, dstWidth);

                dst+= dstPitch;
                srcy_16 += yrIntFloat_16;
            }
        }
        else {
            UInt32 xrIntFloat_16 = (srcWidth<<16) / dstWidth;
            UInt32 yrIntFloat_16 = (srcHeight<<16) / dstHeight;

            while (dstHeight-- > 0) {
                ZoomScanLineARGB32ToARGB32(
                        dst, dstWidth,
                        (src + srcPitch * (srcy_16>>16)),
                        xrIntFloat_16);

                dst+= dstPitch;
                srcy_16 += yrIntFloat_16;
            }
        }
    }
    else if (0x00 != srcOpacity) {
       if (interpolation) {
            UInt32 xrIntFloat_16 = ((srcWidth-1)<<16) / dstWidth;
            UInt32 yrIntFloat_16 = ((srcHeight-1)<<16) / dstHeight;

            while (dstHeight-- > 0) {
                UInt32 v_8 = (srcy_16 & 0xFFFF)>>8;

                BilinearScanLineARGB32ToARGB32WithOpacity(
                        dst,
                        (src + srcPitch * (srcy_16>>16)),
                        srcPitch, v_8, xrIntFloat_16, dstWidth, srcOpacity);

                dst+= dstPitch;
                srcy_16 += yrIntFloat_16;
            }
        }
        else {
            UInt32 xrIntFloat_16 = (srcWidth<<16) / dstWidth;
            UInt32 yrIntFloat_16 = (srcHeight<<16) / dstHeight;

            while (dstHeight-- > 0) {
                ZoomScanLineARGB32ToARGB32WithOpacity(
                        dst, dstWidth,
                        (src + srcPitch * (srcy_16>>16)),
                        xrIntFloat_16, srcOpacity);

                dst+= dstPitch;
                srcy_16 += yrIntFloat_16;
            }
        }
    }
}

Void A8StretchBlit2RGB24(
                Address dst, Int32 dstX, Int32 dstY,
                Int32 dstWidth, Int32 dstHeight, Int32 dstPitch,
                Address src, Int32 srcX, Int32 srcY,
                Int32 srcWidth, Int32 srcHeight, Int32 srcPitch,
                UInt8 srcOpacity,
                UInt8 interpolation,
                Color color)
{
    assert(dst && src);
    assert(srcWidth > 0 && srcHeight > 0);
    assert(dstWidth > 0 && dstHeight > 0);
    assert(dstX >= 0 && dstY >= 0 && srcX >= 0 && srcY >= 0);

    UInt32 srcy_16 = 0;
    src += srcPitch * srcY + srcX;
    dst += dstPitch * dstY + (dstX<<2);

    Pixel srcColor = *(Pixel*)&color;

    if (0 == srcOpacity) {
        return;
    }
    else if (0xFF != srcOpacity) {
        srcColor.a = (srcColor.a * srcOpacity)>>8;
        srcColor.r = (srcColor.r * srcOpacity)>>8;
        srcColor.g = (srcColor.g * srcOpacity)>>8;
        srcColor.b = (srcColor.b * srcOpacity)>>8;
    }

    UInt32 xrIntFloat_16 = (srcWidth<<16) / dstWidth;
    UInt32 yrIntFloat_16 = (srcHeight<<16) / dstHeight;

    if (0xFF == srcColor.a) {
        if (interpolation) {
            while (dstHeight-- > 0) {
                UInt32 v_8 = (srcy_16 & 0xFFFF)>>8;

                BilinearScanLineA8ToRGB24(
                        dst, dstWidth,
                        (src + srcPitch * (srcy_16>>16)), srcPitch,
                        xrIntFloat_16, v_8, srcColor);

                dst+= dstPitch;
                srcy_16 += yrIntFloat_16;
            }
        }
        else {
            while (dstHeight-- > 0) {
                ZoomScanLineA8ToRGB24(
                        dst, dstWidth,
                        (src + srcPitch * (srcy_16>>16)),
                        xrIntFloat_16, srcColor);

                dst+= dstPitch;
                srcy_16 += yrIntFloat_16;
            }
        }
    }
    else if (0x00 != srcColor.a) {
       if (interpolation) {
            while (dstHeight-- > 0) {
                UInt32 v_8 = (srcy_16 & 0xFFFF)>>8;

                BilinearScanLineA8ToRGB24WithColorAlpha(
                        dst, dstWidth,
                        (src + srcPitch * (srcy_16>>16)), srcPitch,
                        xrIntFloat_16, v_8, srcColor);

                dst+= dstPitch;
                srcy_16 += yrIntFloat_16;
            }
        }
        else {
            while (dstHeight-- > 0) {
                ZoomScanLineA8ToRGB24WithColorAlpha(
                        dst, dstWidth,
                        (src + srcPitch * (srcy_16>>16)),
                        xrIntFloat_16, srcColor);

                dst+= dstPitch;
                srcy_16 += yrIntFloat_16;
            }
        }
    }
}

Void A8StretchBlit2ARGB32(
                Address dst, Int32 dstX, Int32 dstY,
                Int32 dstWidth, Int32 dstHeight, Int32 dstPitch,
                Address  src, Int32 srcX, Int32 srcY,
                Int32 srcWidth, Int32 srcHeight, Int32 srcPitch,
                UInt8 srcOpacity,
                UInt8 interpolation,
                Color color)
{
    assert(dst && src);
    assert(dstWidth > 0 && dstHeight > 0);
    assert(srcWidth > 0 && srcHeight > 0);
    assert(dstX >= 0 && dstY >= 0 && srcX >= 0 && srcY >= 0);

    UInt32 srcy_16 = 0;
    src += srcPitch * srcY + srcX;
    dst += dstPitch * dstY + (dstX<<2);

    Pixel srcColor = *(Pixel*)&color;

    if (0 == srcOpacity) {
        return;
    }
    else if (0xFF != srcOpacity) {
        srcColor.a = (srcColor.a * srcOpacity)>>8;
        srcColor.r = (srcColor.r * srcOpacity)>>8;
        srcColor.g = (srcColor.g * srcOpacity)>>8;
        srcColor.b = (srcColor.b * srcOpacity)>>8;
    }

    UInt32 xrIntFloat_16 = (srcWidth<<16) / dstWidth;
    UInt32 yrIntFloat_16 = (srcHeight<<16) / dstHeight;

    if (0xFF == srcColor.a) {
        if (interpolation) {
            while (dstHeight-- > 0) {
                UInt32 v_8 = (srcy_16 & 0xFFFF)>>8;

                BilinearScanLineA8ToARGB32(
                        dst, dstWidth,
                        (src + srcPitch * (srcy_16>>16)), srcPitch,
                        xrIntFloat_16, v_8, srcColor);

                dst+= dstPitch;
                srcy_16 += yrIntFloat_16;
            }
        }
        else {
            while (dstHeight-- > 0) {
                ZoomScanLineA8ToARGB32(
                        dst, dstWidth,
                        (src + srcPitch * (srcy_16>>16)),
                        xrIntFloat_16, srcColor);

                dst+= dstPitch;
                srcy_16 += yrIntFloat_16;
            }
        }
    }
    else if (0x00 != srcColor.a) {
       if (interpolation) {
            while (dstHeight-- > 0) {
                UInt32 v_8 = (srcy_16 & 0xFFFF)>>8;

                BilinearScanLineA8ToARGB32WithColorAlpha(
                        dst, dstWidth,
                        (src + srcPitch * (srcy_16>>16)), srcPitch,
                        xrIntFloat_16, v_8, srcColor);

                dst+= dstPitch;
                srcy_16 += yrIntFloat_16;
            }
        }
        else {
            while (dstHeight-- > 0) {
                ZoomScanLineA8ToARGB32WithColorAlpha(
                        dst, dstWidth,
                        (src + srcPitch * (srcy_16>>16)),
                        xrIntFloat_16, srcColor);

               dst+= dstPitch;
                srcy_16 += yrIntFloat_16;
            }
        }
    }
}

Void RGB24ToRGB565(
                Address dst, Int32 dstWidth, Int32 dstHeight, Int32 dstPitch,
                Address src, Int32 srcPitch,
                Int32 x, Int32 y, Int32 width, Int32 height,
                Int32 orientation)
{
    assert(dst && src);
    assert(dstWidth > 0 && dstHeight > 0);
    assert(dstPitch > 0 && srcPitch > 0);
    assert(x >= 0 && y >= 0 && width > 0 && height >= 0);

    src += y * srcPitch + (x<<2);

    switch (orientation) {
        case 0:
            dst += y * dstPitch + (x<<1);
            while (height--) {
                ScanLineRECT888To565(dst, src, width);
                dst += dstPitch;
                src += srcPitch;
            }
            break;

        case 1:
            dst += x * dstPitch + ((dstWidth - y - 1)<<1);
            while (height--) {
                ScanLineRECT888To565RCW(dst, src, width, dstPitch);
                dst = (Address)((UInt16*)dst - 1);
                src += srcPitch;
            }
            break;

        case 2:
            dst += (dstHeight - y - 1) * dstPitch + ((dstWidth - x)<<1);
            while (height--) {
                ScanLineRECT888To565FLIP(dst, src, width);
                dst -= dstPitch;
                src += srcPitch;
            }
            break;

        case 3:
            dst += (dstHeight - x - 1) * dstPitch + (y<<1);
            while (height--) {
                ScanLineRECT888To565RCCW(dst, src, width, dstPitch);
                dst = (Address)((UInt16*)dst + 1);
                src += srcPitch;
            }
            break;
    }
}

Void RGB24ToRGB666(
                Address dst, Int32 dstWidth, Int32 dstHeight, Int32 dstPitch,
                Address src, Int32 srcPitch,
                Int32 x, Int32 y, Int32 width, Int32 height,
                Int32 orientation)
{
    assert(dst && src);
    assert(dstWidth > 0 && dstHeight > 0);
    assert(dstPitch > 0 && srcPitch > 0);
    assert(x >= 0 && y >= 0 && width > 0 && height >= 0);

    src += y * srcPitch + (x<<2);

    switch (orientation) {
        case 0:
            dst += y * dstPitch + (x<<2);
            while (height--) {
                ScanLineRECT888To666(dst, src, width);
                dst += dstPitch;
                src += srcPitch;
            }
            break;

        case 1:
            dst += x * dstPitch + ((dstWidth - y - 1)<<2);
            while (height--) {
                ScanLineRECT888To666RCW(dst, src, width, dstPitch);
                dst = (Address)((UInt32*)dst - 1);
                src += srcPitch;
            }
            break;

        case 2:
            dst += (dstHeight - y - 1) * dstPitch + ((dstWidth - x)<<2);
            while (height--) {
                ScanLineRECT888To666FLIP(dst, src, width);
                dst -= dstPitch;
                src += srcPitch;
            }
            break;

        case 3:
            dst += (dstHeight - x - 1) * dstPitch + (y<<2);
            while (height--) {
                ScanLineRECT888To666RCCW(dst, src, width, dstPitch);
                dst = (Address)((UInt32*)dst + 1);
                src += srcPitch;
            }
            break;
    }
}

Void RGB24ToRGB888(
                Address dst, Int32 dstWidth, Int32 dstHeight, Int32 dstPitch,
                Address src, Int32 srcPitch,
                Int32 x, Int32 y, Int32 width, Int32 height,
                Int32 orientation)
{
    assert(dst && src);
    assert(dstWidth > 0 && dstHeight > 0);
    assert(dstPitch > 0 && srcPitch > 0);
    assert(x >= 0 && y >= 0 && width > 0 && height >= 0);
    assert(orientation>=0 && orientation < 4);

    src += y * srcPitch + (x<<2);

    switch (orientation) {
        case 0:
            dst += y * dstPitch + (x<<2);
            while (height--) {
                ScanLineRGB24ToRGB24(dst, src, width);
                dst += dstPitch;
                src += srcPitch;
            }
            break;

        case 1:
            dst += x * dstPitch + ((dstWidth - y - 1)<<2);
            while (height--) {
                ScanLineRECT888To888RCW(dst, src, width, dstPitch);
                dst = (Address)((UInt32*)dst - 1);
                src += srcPitch;
            }
            break;

        case 2:
            dst += (dstHeight - y - 1) * dstPitch + ((dstWidth - x)<<2);
            while (height--) {
                ScanLineRECT888To888FLIP(dst, src, width);
                dst -= dstPitch;
                src += srcPitch;
            }
            break;

        case 3:
            dst += (dstHeight - x - 1) * dstPitch + (y<<2);
            while (height--) {
                ScanLineRECT888To888RCCW(dst, src, width, dstPitch);
                dst = (Address)((UInt32*)dst + 1);
                src += srcPitch;
            }
            break;
    }
}

Void RGB24Blit2RGB24WithOrientation(
                Address dst, Int32 dstX, Int32 dstY, Int32 dstPitch,
                Address src, Int32 srcX, Int32 srcY, Int32 width, Int32 height, Int32 srcPitch,
                Int32 orientation)
{
    assert(dst && src);
    assert(width > 0 && height >= 0);
    assert(dstPitch > 0 && srcPitch > 0);
    assert(dstX >= 0 && dstY >= 0 && srcX >= 0 && srcY >= 0);

    src += srcY * srcPitch + (srcX<<2);
    dst += dstY * dstPitch + (dstX<<2);

    switch (orientation) {
        case 0:
            while (height--) {
                ScanLineRGB24ToRGB24(dst, src, width);
                dst += dstPitch;
                src += srcPitch;
            }
            break;

        case 1:
            while (height--) {
                ScanLineRECT888To888RCW(dst, src, width, dstPitch);
                dst = (Address)((UInt32*)dst - 1);
                src += srcPitch;
            }
            break;

        case 2:
            while (height--) {
                ScanLineRECT888To888FLIP(dst, src, width);
                dst -= dstPitch;
                src += srcPitch;
            }
            break;

        case 3:
            while (height--) {
                ScanLineRECT888To888RCCW(dst, src, width, dstPitch);
                dst = (Address)((UInt32*)dst + 1);
                src += srcPitch;
            }
            break;
    }
}


void WarpPerspective_8u_C4A(const BitmapBufInfo& Src, const BitmapBufInfo& Dst, int nWidth, int nLHeight, int nRHeight)
{

    unsigned int SrcW = Src.width;
    unsigned int SrcH = Src.height>>1;
    unsigned int DstW = nWidth;
    unsigned int DstHL = nLHeight>>1;
    unsigned int DstHR = nRHeight>>1;
    unsigned int DstHX16 = DstHL<<16;

    unsigned int Src_X16 = 0;
    unsigned int Src_Y16 = 0;
    unsigned int SrcXD16 = ((SrcW-1)<<16)/DstW+1;
    unsigned int SrcYD16 = ((SrcH-1)<<16)/DstHL+1;

    unsigned int dst_Pitch = Dst.pitch;
    unsigned int Src_Pitch = Src.pitch;

    Pixel* pSrc = (Pixel*)(Src.address + Src_Pitch * SrcH);
    unsigned int y;

    if (DstHL >= DstHR) {
        Pixel* pDst = (Pixel*)(Dst.address + dst_Pitch * DstHL);
        unsigned int DstHD16 = (DstHL<<16) - (((DstHR + DstHL * (DstW - 1)) <<16) / DstW);
        for (unsigned int x=0; x<DstW; x++) {

            unsigned int DstHX = DstHX16>>16;
            Pixel* PSrcColumn=(pSrc+(Src_X16>>16));
            unsigned long u_8=(Src_X16 & 0xFFFF)>>8;

             Pixel* dst = pDst+x;
             Pixel* dstup = dst;

            Src_Y16 = 0;
            for (y=0; y<DstHX; y++) {
                Pixel* PColor0 = (Pixel*)((unsigned char*)PSrcColumn + Src_Pitch*(Src_Y16>>16));
                Pixel* PColor1 = (Pixel*)((unsigned char*)PSrcColumn - Src_Pitch*(Src_Y16>>16));
                *dst=BilinearQuadARGB32((Address)PColor0,(Address)((unsigned char*)PColor0+Src_Pitch),u_8,(Src_Y16 & 0xFFFF)>>8);
                *dstup=BilinearQuadARGB32((Address)PColor1,(Address)((unsigned char*)PColor1-Src_Pitch),u_8,((Src_Y16 & 0xFFFF))>>8);

                Src_Y16 += SrcYD16;
                ((unsigned char*&)dst)+=dst_Pitch;
                ((unsigned char*&)dstup)-=dst_Pitch;
            }
            for (y=0; y<DstHL - DstHX; y++) {
                *(int*)dst= 0;
                *(int*)dstup= 0;
                ((unsigned char*&)dst)+=dst_Pitch;
                ((unsigned char*&)dstup)-=dst_Pitch;
            }
            SrcYD16 = ((SrcH * DstW)<<16) / (DstHR * x + DstHL * (DstW - x));
            DstHX16 -= DstHD16;
            Src_X16 += SrcXD16;

        }
    }
    else {
        Pixel* pDst = (Pixel*)(Dst.address + dst_Pitch * DstHR);
        unsigned int DstHD16 = (DstHR<<16) - (((DstHL + DstHR * (DstW - 1)) <<16)/ DstW);
        for (unsigned int x=0; x<DstW; x++) {

            unsigned int DstHX = DstHX16>>16;
            Pixel* PSrcColumn=(pSrc+(Src_X16>>16));
            unsigned long u_8=(Src_X16 & 0xFFFF)>>8;

             Pixel* dst = pDst+x;
             Pixel* dstup = dst;

            Src_Y16 = 0;
            for (y=0; y<DstHX; y++) {
                Pixel* PColor0 = (Pixel*)((unsigned char*)PSrcColumn + Src_Pitch*(Src_Y16>>16));
                Pixel* PColor1 = (Pixel*)((unsigned char*)PSrcColumn - Src_Pitch*(Src_Y16>>16));
                *dst=BilinearQuadARGB32((Address)PColor0,(Address)((unsigned char*)PColor0+Src_Pitch),u_8,(Src_Y16 & 0xFFFF)>>8);
                *dstup=BilinearQuadARGB32((Address)PColor1,(Address)((unsigned char*)PColor1-Src_Pitch),u_8,((Src_Y16 & 0xFFFF))>>8);

                Src_Y16 += SrcYD16;
                ((unsigned char*&)dst)+=dst_Pitch;
                ((unsigned char*&)dstup)-=dst_Pitch;
            }
            for (y=0; y<DstHR - DstHX; y++) {
                *(int*)dst= 0;
                *(int*)dstup= 0;
                ((unsigned char*&)dst)+=dst_Pitch;
                ((unsigned char*&)dstup)-=dst_Pitch;
            }
            SrcYD16 = ((SrcH * DstW)<<16) / (DstHR * x + DstHL * (DstW - x));
            DstHX16 += DstHD16;
            Src_X16 += SrcXD16;
        }
    }
}


void WarpPerspectiveH_8u_C4A(const BitmapBufInfo& Src, const BitmapBufInfo& Dst, int nWidthT, int nWidthD, int nHeight)
{


    unsigned int SrcW = Src.width>>1;
    unsigned int SrcH = Src.height;
    unsigned int DstH = nHeight;
    unsigned int DstWT = nWidthT>>1;
    unsigned int DstWD = nWidthD>>1;
    unsigned int DstWX16 = DstWT<<16;

    if ((DstH<=1) || (DstWT<=1)) return;

    unsigned int Src_X16 = 0;
    unsigned int Src_Y16 = 0;
    unsigned int SrcYD16 = ((((SrcH-1)<<16))/(DstH))+1;
    unsigned int SrcXD16 = ((((SrcW-1)<<16))/(DstWT))+1;

    unsigned int dst_Pitch = Dst.pitch;
    unsigned int Src_Pitch = Src.pitch;

    Pixel* pSrc = (Pixel*)Src.address + SrcW;

    unsigned int y;

    if (DstWT >= DstWD) {
        Pixel* pDst = (Pixel*)Dst.address + DstWT;
        unsigned int DstWD16 = (DstWT<<16) - (((DstWD + DstWT * (DstH - 1)) <<16)/ DstH);
        for (unsigned int x=0; x<DstH; x++) {

            unsigned int DstWX = DstWX16>>16;
            Pixel* PSrcColumn=(Pixel*)((unsigned char*)pSrc+Src_Pitch*(Src_Y16>>16));
            unsigned long v_8=(Src_Y16 & 0xFFFF)>>8;

             Pixel* dst = (Pixel*)((unsigned char*)pDst+x*dst_Pitch);
             Pixel* dstl = dst;

            Src_X16 = 0;
            for (y=0; y<DstWX; y++) {
                Pixel* PColor0 = PSrcColumn + (Src_X16>>16);
                Pixel* PColor1 = PSrcColumn - (Src_X16>>16);
                *dst=BilinearQuadARGB32((Address)PColor0,(Address)((unsigned char*)PColor0+Src_Pitch), (Src_X16 & 0xFFFF)>>8, v_8);
                *dstl=BilInearNC4A(PColor1,(Pixel*)((unsigned char*)PColor1+Src_Pitch), (Src_X16 & 0xFFFF)>>8, v_8);

                Src_X16 += SrcXD16;
                dst++;
                dstl--;
            }
            for (y=0; y<DstWT - DstWX; y++) {
                *(int*)dst= 0;
                *(int*)dstl= 0;
                dst++;
                dstl--;
            }
            SrcXD16 = ((SrcW * DstH)<<16) / (DstWD * x + DstWT * (DstH - x));
            DstWX16 -= DstWD16;
            Src_Y16 += SrcYD16;

        }
    }
    else {
        Pixel* pDst = (Pixel*)Dst.address + DstWD;
        unsigned int DstWD16 = (DstWD<<16) - (((DstWT + DstWD * (DstH - 1)) <<16)/ DstH);
        for (unsigned int x=0; x<DstH; x++) {

            unsigned int DstWX = DstWX16>>16;
            Pixel* PSrcColumn=(Pixel*)((unsigned char*)pSrc+Src_Pitch*(Src_Y16>>16));
            unsigned long v_8=(Src_Y16 & 0xFFFF)>>8;

             Pixel* dst = (Pixel*)((unsigned char*)pDst+x*dst_Pitch);
             Pixel* dstl = dst;

            Src_X16 = 0;
            for (y=0; y<DstWX; y++) {
                Pixel* PColor0 = PSrcColumn + (Src_X16>>16);
                Pixel* PColor1 = PSrcColumn - (Src_X16>>16);
                *dst=BilinearQuadARGB32((Address)PColor0, (Address)((unsigned char*)PColor0+Src_Pitch), (Src_X16 & 0xFFFF)>>8, v_8);
                *dstl=BilInearNC4A(PColor1,(Pixel*)((unsigned char*)PColor1+Src_Pitch), (Src_X16 & 0xFFFF)>>8, v_8);

                Src_X16 += SrcXD16;
                dst++;
                dstl--;
            }
            for (y=0; y<DstWD - DstWX; y++) {
                *(int*)dst= 0;
                *(int*)dstl= 0;
                dst++;
                dstl--;
            }
            SrcXD16 = ((SrcW * DstH)<<16) / (DstWD * x + DstWT * (DstH - x));
            DstWX16 += DstWD16;
            Src_Y16 += SrcYD16;
        }
    }
}


void ShearBilinear_8u_C4A(const BitmapBufInfo& Src, const BitmapBufInfo& Dst, int offset)
{
    if ((abs(offset)+1)>Dst.width)
        return;
    Pixel* pSrc = (Pixel*)Src.address;

    unsigned int SrcW = Src.width;
    unsigned int SrcH = Src.height;
    unsigned int DstW = Dst.width - abs(offset);
    unsigned int DstH =  Dst.height;

    unsigned int SrcXD16 = ((SrcW-1)<<16)/(DstW)+1;
    unsigned int SrcYD16 = ((SrcH-1)<<16)/(DstH)+1;
    unsigned int DstSX16 = (abs(offset)<<16)/DstH;

    int dstwidth = DstW;
    int Src_Pitch = Src.pitch;

    unsigned long srcy_16=0;
    int x;

    if (offset>=0) {
        Pixel* pDst = (Pixel*)Dst.address;
        unsigned int Dst_SX16 = 0;
        for (int y=0;y<Dst.height;++y) {
            unsigned long v_8=(srcy_16 & 0xFFFF)>>8;
            Pixel* PSrcLineColor= (Pixel*)((unsigned char*)(pSrc)+Src_Pitch*(srcy_16>>16));

            unsigned long srcx_16 = (0xFFFF - ((Dst_SX16) & 0xFFFF))*SrcW/DstW;

            for (x=0; x<int(Dst_SX16>>16); x++) {
                *(int*)pDst= 0;
                pDst++;
            }
            for (x=0; x<dstwidth; x++)
            {
                Pixel* PColor0=&PSrcLineColor[srcx_16>>16];
                *pDst=BilinearQuadARGB32((Address)PColor0,(Address)((unsigned char*)PColor0+Src_Pitch),(srcx_16 & 0xFFFF)>>8,v_8);
                srcx_16+=SrcXD16;
                pDst++;
            }
            for (x=0; x<offset - int(Dst_SX16>>16); x++) {
                *(int*)pDst= 0;
                pDst++;
            }
            Dst_SX16+=DstSX16;
            srcy_16+=SrcYD16;
            pDst = (Pixel*)(Dst.address + y * Dst.pitch);
        }
    }
    else {
        Pixel* pDst = (Pixel*)Dst.address - offset;
        unsigned int Dst_SX16 = abs(offset)<<16;
        for (int y=0;y<Dst.height;++y) {
            unsigned long v_8=(srcy_16 & 0xFFFF)>>8;
            Pixel* PSrcLineColor= (Pixel*)((unsigned char*)(pSrc)+Src_Pitch*(srcy_16>>16));

            unsigned long srcx_16 = (0xFFFF - ((Dst_SX16) & 0xFFFF))*SrcW/DstW;
            for (x=0; x<int(Dst_SX16>>16); x++) {
                *(int*)pDst= 0;
                pDst++;
            }
            for (x=0; x<dstwidth; x++)
            {
                Pixel* PColor0=&PSrcLineColor[srcx_16>>16];
                *pDst=BilinearQuadARGB32((Address)PColor0,(Address)((unsigned char*)PColor0+Src_Pitch),(srcx_16 & 0xFFFF)>>8,v_8);
                srcx_16+=SrcXD16;
                pDst++;
            }
            for (x=0; x<-offset - int(Dst_SX16>>16); x++) {
                *(int*)pDst= 0;
                pDst++;
            }
            Dst_SX16-=DstSX16;
            srcy_16+=SrcYD16;
            pDst = (Pixel*)(Dst.address + y * Dst.pitch);
        }
    }
}


void CurveBilinear_8u_C4A(const BitmapBufInfo& Src, const BitmapBufInfo& Dst, int* aSampleX16, int width)
{
    Pixel* pSrc = (Pixel*)Src.address;

    int SrcW = Src.width;
    int SrcH = Src.height;
    int DstW = Dst.width;
    int DstH = Dst.height;

    unsigned int SrcXD16 = ((SrcW-1)<<16)/(width)+1;
    unsigned int SrcYD16 = ((SrcH-1)<<16)/(DstH)+1;
    unsigned int Dst_SX16 = aSampleX16[0];

    int dstwidth = width;
    int Src_Pitch = Src.pitch;

    unsigned long srcy_16=0;
    int x;

    Pixel* pDst = (Pixel*)Dst.address + (Dst_SX16>>16);

    for (int y=0;y<Dst.height;y++) {

        Dst_SX16 = aSampleX16[y];

        unsigned long v_8=(srcy_16 & 0xFFFF)>>8;
        Pixel* PSrcLineColor= (Pixel*)((unsigned char*)(pSrc)+Src_Pitch*(srcy_16>>16));
        unsigned long srcx_16 = (0xFFFF - ((Dst_SX16) & 0xFFFF))*SrcW/dstwidth;

        for (x=0; x<int(Dst_SX16>>16); x++) {
            *(int*)pDst= 0;
            pDst++;
        }
        for (x=0; x<dstwidth; x++)
        {
            Pixel* PColor0=&PSrcLineColor[srcx_16>>16];
            *pDst=BilinearQuadARGB32((Address)PColor0,(Address)((unsigned char*)PColor0+Src_Pitch),(srcx_16 & 0xFFFF)>>8,v_8);
            srcx_16+=SrcXD16;
            pDst++;
        }
        for (x=0; x<DstW - dstwidth - int(Dst_SX16>>16); x++) {
            *(int*)pDst= 0;
            pDst++;
        }
        srcy_16+=SrcYD16;
        pDst = (Pixel*)(Dst.address + y * Dst.pitch);
    }
}

void DrawAAPolygon(
            Point * leftVertexList, Int32 LEdgeNum,
            Point * rightVertexList, Int32 REdgeNum,
            const BitmapBufInfo * srcImg, const BitmapBufInfo * dstImg,
            Int32 level)
{
    int startY = leftVertexList[0].y;
    int height = leftVertexList[LEdgeNum].y - leftVertexList[0].y;
    ScanLineList * scanlinelist = new ScanLineList[height+2];

    int i;
    for (i=0;i<LEdgeNum;i++) {
        ScanLeftAAEdge(leftVertexList[i], leftVertexList[i+1], scanlinelist, startY, height, srcImg, dstImg, level);
    }
    for (i=0;i<REdgeNum;i++) {
        ScanRightAAEdge(rightVertexList[i], rightVertexList[i+1], scanlinelist, startY, height, srcImg, dstImg, level);
    }

    FillPolygon(scanlinelist, startY, height, srcImg, dstImg, level);

    if (scanlinelist)
        delete [] scanlinelist;
}

void GradientFillColor(
            int* gradientTable,
            int x0, int y0,
            int vx, int vy,
            const BitmapBufInfo *img)
{
    int x,y;
    unsigned char* imgDst = (unsigned char*)img->address;
    int* dst = (int*)imgDst;
    int width = img->width;
    int pitch = img->pitch;
    //int x_16 = x0<<16;
    int len = vx*vx+vy*vy;

#ifndef _EVC

    int incx_16 = int(((long long int)(vx)<<24)/len);
    int incy_16 = int(((long long int)(vy)<<24)/len);

#else

    int incx_16 = int((_int64(vx)<<24)/len);
    int incy_16 = int((_int64(vy)<<24)/len);

#endif

    int gx_16 = 0;
    int temp;
    int gx0_16 = -incx_16*x0;
    x0 = width-1;

    for(y=y0;y>=0;y--) {
        gx_16 = gx0_16;
        dst=(int*)(imgDst+pitch*y);
        for (x=x0;x>=0;x--) {
            temp = (gx_16>>16);
            if (temp<0) temp=0;
            if (temp>255) temp=255;
            *dst++ = gradientTable[temp];
            gx_16+=incx_16;
        }
        gx0_16 += incy_16;
    }
}
